﻿using Newtonsoft.Json.Linq;
using Wechat_PublicNumber.SettingModel;

namespace Wechat_PublicNumber.Common
{
    [Injection(DIPattern.Singleton, InitMethod = nameof(Init))]
    public class WechatAccessToken
    {
        #region DI
        [Autowired]
        private HttpClinetHelper _clinetHelper;

        [Autowired]
        private WxSetting _wxSetting;

        [Autowired]
        private ILog _logger;
        #endregion

        private void Init()
        {
            Console.WriteLine("WechatAccessToken Init");
            Dictionary<string, string> par = new Dictionary<string, string>();
            par.Add("grant_type", "client_credential");
            par.Add("appid", _wxSetting.AppID);
            par.Add("secret", _wxSetting.AppSecret);

            var responestring = _clinetHelper.JsonGet<string>(Wechat_Url.AccessToken_Get + $"?grant_type=client_credential&appid={_wxSetting.AppID}&secret={_wxSetting.AppSecret}").Result;

            if (string.IsNullOrEmpty(responestring)) throw new Exception("Request not get WxAccessToken");
            else
            {
                JObject obj = JObject.Parse(responestring);
                _logger.Debug($"Get WxAccessToken {(obj["errcode"] == null ? "Success" : "Error")}," + responestring, "WechatAccessToken");
                if (obj["errcode"] == null)
                {
                    _access_token = obj["access_token"].ToString();
                    expires_in = double.Parse(obj["expires_in"].ToString());
                    expires_time = DateTime.Now.AddSeconds(expires_in - 180);
                }
                else
                {
                    _logger.Error("WxAccessToken Rrror,Respone：" + responestring, "WechatAccessToken");
                }
            }
        }

        private string _access_token { get; set; }

        private readonly object tokenLock = new object();

        public string access_token
        {
            get
            {
                lock (tokenLock)
                {
                    //当前时间大于过期时间就重新获取access_token
                    if (expires_time < DateTime.Now) Init();
                }
                return _access_token;
            }
            set { }
        }

        private double expires_in { get; set; }

        public DateTime expires_time { get; set; }
    }
}
